import memoizeOne from 'memoize-one';
import isEqual from 'lodash/isEqual';
import {sysMenuUserApi} from '@/services/api';
import {formatMessage} from 'umi/locale';
import Authorized from '@/utils/Authorized';
import {isFakeData} from '@/utils/utils';

const {check} = Authorized;

// Conversion router to menu.
function formatter(data, parentAuthority, parentName) {
  return data
    .map(item => {
      if (!item.name || !item.path) {
        return null;
      }
      let locale = 'menu';
      if (parentName) {
        locale = `${parentName}.${item.name}`;
      } else {
        locale = `menu.${item.name}`;
      }

      const result = {
        ...item,
        name: formatMessage({id: locale, defaultMessage: item.name}),
        locale,
        authority: item.authority || parentAuthority,
      };
      if (item.routes) {
        const children = formatter(item.routes, item.authority, locale);
        // Reduce memory usage
        result.children = children;
      }
      delete result.routes;
      return result;
    })
    .filter(item => item);
}

const memoizeOneFormatter = memoizeOne(formatter, isEqual);

/**
 * get SubMenu or Item
 */
const getSubMenu = item => {
  // doc: add hideChildrenInMenu
  if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) {
    return {
      ...item,
      children: filterMenuData(item.children), // eslint-disable-line
    };
  }
  return item;
};

/**
 * filter menuData
 */
const filterMenuData = menuData => {
  if (!menuData) {
    return [];
  }
  return menuData
    .filter(item => item.name && !item.hideInMenu)
    .map(item => check(item.authority, getSubMenu(item)))
    .filter(item => item);
};
/**
 * 获取面包屑映射
 * @param {Object} menuData 菜单配置
 */
const getBreadcrumbNameMap = menuData => {
  const routerMap = {};

  const flattenMenuData = data => {
    data.forEach(menuItem => {
      if (menuItem.children) {
        flattenMenuData(menuItem.children);
      }
      // Reduce memory usage
      routerMap[menuItem.path] = menuItem;
    });
  };
  flattenMenuData(menuData);
  return routerMap;
};

const setMenuList = menuData => {
  this.setState({menuData}, console.log(this.data.menuData, '改变状态'));
};

const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual);

//============ 下面三个menu开头的方法是转换menu菜单用的 段大志 ==============
let menuList = [];
const menuFindByParent = parentId => {
  const rootMenus = menuList
    .filter(
      en =>
        en.parentId === parentId &&
        en.type !== null &&
        en.type !== undefined &&
        en.type !== 2 &&
        en.urlAntd !== null &&
        en.urlAntd !== undefined &&
        en.urlAntd.indexOf('druid/sql.html') === -1
    )
    .map(en => ({
      name: en.name,
      icon: en.iconAntd,
      authority: ['admin', 'user'],
      path: en.urlAntd,
      menuId: en.menuId,
      parentId: en.parentId,
      type: en.type,
      orderNum: en.orderNum,
      target: en.target,
    }))
    .map(en => {
      if (en.path && !(en.path.includes('http') || en.path.includes('https'))) {
        en.path = `/${en.path.replace('.html', '')}`;
      }
      if (!en.target) {
        delete en.target;
      }
      return en;
    })
    .sort((a, b) => a.orderNum - b.orderNum);
  return rootMenus || [];
};

const menuFindTreeList = menus => {
  const subMenuList = [];
  for (let i = 0; i < menus.length; i += 1) {
    const menu = menus[i];
    if (menu.type === 0 || menu.type === 1) {
      //children
      menu.children = menuFindTreeList(menuFindByParent(menu.menuId));
    }
    subMenuList.push(menu);
  }
  return subMenuList;
};

//转换菜单数组-->合适的数据
const menuConversionList = () => {
  //查询根菜单列表
  const rootMenus = menuFindByParent(0);
  //递归获取子菜单
  menuFindTreeList(rootMenus);
  //外层包裹一下
  return [...rootMenus];
};

export default {
  namespace: 'menu',

  state: {
    menuData: [],
    breadcrumbNameMap: {},
  },

  effects: {
    * getMenuData({payload}, {put, call}) {
      const {routes, authority} = payload;
      // 动态菜单 动态路由 https://github.com/umijs/umi/issues/944
      // eslint-disable-next-line no-console
      console.log('获取菜单数据...');
      let menuData = filterMenuData(memoizeOneFormatter(routes, authority));

      //段大志修改
      if (!isFakeData()) {
        //这些代码是获取动态菜单的东西,本地演示，可以直接注释
        //umi 配置形式的菜单 路由文件 router.config.js
        const response = yield call(sysMenuUserApi);
        // eslint-disable-next-line no-console
        console.log('获取菜单数据成功...');

        if (response.code === 0) {
          window.permissions = response.permissions || [];
          //这里进行转换 菜单menu
          menuList = response.menuList || [];
          menuData = menuConversionList();
          // eslint-disable-next-line no-console
          console.error('转换菜单数组-->合适的数据， 返回数据了');
        } else {
          // @HACK
          /* eslint-disable no-underscore-dangle */
          window.g_app._store.dispatch({
            type: 'login/logout',
          });
          return;
        }
      }

      const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(menuData);
      // const menuData = yield select(state => state);
      yield put({
        type: 'save',
        payload: {menuData, breadcrumbNameMap},
      });
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        ...action.payload,
      };
    },
  },
};
